package service

import (
	"chat/conf"
	"chat/ret"
	"encoding/json"
	"fmt"
	"github.com/gorilla/websocket"
	"log"
	"strconv"
)

func (manager *ClientManager) Start() { // 传引用  才有成员方法的味道
	for {
		log.Println("<---监听管道通信--->")
		select {
		case conn := <-Manager.Register: // 建立连接
			log.Printf("建立新连接: %v", conn.ID)
			Manager.Clients[conn.ID] = conn
			replyMsg := &ReplyMsg{
				Code:    ret.WebsocketSuccess,
				Content: "已连接至服务器",
			}
			msg, _ := json.Marshal(replyMsg)
			_ = conn.Socket.WriteMessage(websocket.TextMessage, msg)
		case conn := <-Manager.Unregister: // 断开连接
			log.Printf("连接失败:%v", conn.ID)
			if _, ok := Manager.Clients[conn.ID]; ok {
				replyMsg := &ReplyMsg{
					Code:    ret.WebsocketEnd,
					Content: "连接已断开",
				}
				msg, _ := json.Marshal(replyMsg)
				_ = conn.Socket.WriteMessage(websocket.TextMessage, msg)
				close(conn.Send)
				delete(Manager.Clients, conn.ID)
			}
		case broadcast := <-Manager.Broadcast: // 广播信息
			fmt.Println("普通发消息难道走的是广播消息的路子吗")
			message := broadcast.Message
			sendId := broadcast.Client.SendID
			dest := broadcast.Client.Dest
			flag := false // 默认对方不在线

			// 设置10000  作为广播信道
			if dest == "10000" { //  广播任务基本完成  但是现在 这个配置很戳  我想一下
				fmt.Println("发送广播消息")

				sendCnt := 0

				for _, conn := range Manager.Clients {
					// 遍历 在线客户端集合    发送广播消息
					conn.Send <- message
					sendCnt++
				}
				fmt.Printf("累计发送给了 %d 个客户端", sendCnt)
				content := "累计发送给了" + strconv.Itoa(sendCnt) + "个客户端"
				replyMsg := &ReplyMsg{
					Code:    ret.WebsocketOnlineReply, // 到时候随便赋一个 值吧   广播消息编码
					Content: content,
				}

				msg, _ := json.Marshal(replyMsg)

				//  写回广播消息 回执
				_ = broadcast.Client.Socket.WriteMessage(websocket.TextMessage, msg)

				//TODO  insert逻辑

			} else {

				for id, conn := range Manager.Clients {
					if id != sendId {
						// websocket连接是跟server建立的 只是通过 这个参数去找私发的对象
						continue
					}
					select {

					// 这是本质吧  这就是往   客户机管道传数据
					case conn.Send <- message:
						flag = true
					default:
						close(conn.Send)
						delete(Manager.Clients, conn.ID)
					}
				}
				id := broadcast.Client.ID
				if flag {
					log.Println("对方在线应答")
					replyMsg := &ReplyMsg{
						Code:    ret.WebsocketOnlineReply,
						Content: "对方在线应答",
					}
					msg, err := json.Marshal(replyMsg)
					_ = broadcast.Client.Socket.WriteMessage(websocket.TextMessage, msg) // 写会消息给发送方
					err = InsertMsg(conf.MongoDBName, id, string(message), 1, int64(3*month))
					if err != nil {
						fmt.Println("InsertOneMsg Err", err)
					}
				} else {
					// 不在线必须手动 调api才行吗？
					log.Println("对方不在线")
					replyMsg := ReplyMsg{
						Code:    ret.WebsocketOfflineReply,
						Content: "对方不在线应答",
					}
					msg, err := json.Marshal(replyMsg)
					_ = broadcast.Client.Socket.WriteMessage(websocket.TextMessage, msg)
					err = InsertMsg(conf.MongoDBName, id, string(message), 0, int64(3*month))
					if err != nil {
						fmt.Println("InsertOneMsg Err", err)
					}
				}

			}

		}
	}
}
